﻿/*  (c) 2008 Benjamin Schroeter
 *  This file is part of JaDAL - Just another DSL-Tools Addon Library
 *  and licensed under the New BSD License
 *  For more information please visit http://www.codeplex.com/JaDAL */
using System;
using System.Collections;
using System.ComponentModel.Design;
using System.Windows.Forms;
using Microsoft.VisualStudio.Modeling;
using Microsoft.VisualStudio.Modeling.Diagrams;
using Microsoft.VisualStudio.Modeling.Shell;

namespace BenjaminSchroeter.DslTools
{
    /// <summary>
    /// Implements the logic for the ProcessOnStatus callback
    /// methods for the commands.
    /// </summary>
    public static class OnStatusDeleteCommandLogic
    {
        /// <summary>
        /// Use this method from within the MyLanguageCommandSet class
        /// in the ProcessOnStatusDeleteCommand() method.
        /// </summary>
        /// <example>
        /// partial class MyLanguageCommandSet
        /// {
        ///    protected override void ProcessOnStatusDeleteCommand(MenuCommand command)
        ///    {
        ///        OnStatusDeleteCommandLogic.ForEditor(command, this.CurrentDocumentSelection, base.ProcessOnStatusDeleteCommand);
        ///    }
        /// }
        /// </example>
        public static void ForEditor(MenuCommand command, ICollection currentDocumentSelection, Action<MenuCommand> baseFunction)
        {
            bool restrictDelete = false;
            // check all currently selected elements
            foreach (object o in currentDocumentSelection)
            {
                if (o is IDynamicCanDelete)
                {
                    if (!(o as IDynamicCanDelete).CanDelete())
                    {
                        restrictDelete = true;
                        break;
                    }
                }

                // if it is a shape (aka. PresentationElement)
                if (o is PresentationElement)
                {
                    // check also the model element of the shape
                    if ((o as PresentationElement).ModelElement is IDynamicCanDelete)
                    {
                        IDynamicCanDelete element = (IDynamicCanDelete)(o as PresentationElement).ModelElement;
                        if (!element.CanDelete())
                        {
                            restrictDelete = true;
                            break;
                        }
                    }
                }
            }

            // hide the command
            if (restrictDelete)
            {
                command.Visible = false;
                command.Enabled = false;
            }
            else
                // call the base implementation
                baseFunction(command);
        }

        /// <summary>
        /// Use this method from within the MyLanguageExplorer class
        /// in the ProcessOnStatusDeleteCommand() method.
        /// </summary>
        /// <example>
        /// partial class MyLanguageExplorer
        /// {
        ///    protected override void ProcessOnStatusDeleteCommand(MenuCommand cmd)
        ///    {
        ///        OnStatusDeleteCommandLogic.ForExplorerDelete(cmd, this.SelectedElement, base.ProcessOnStatusDeleteCommand);
        ///    }
        /// }
        /// </example>
        public static void ForExplorerDelete(MenuCommand cmd, ModelElement selectedElement, Action<MenuCommand> baseFunction)
        {
            // check the selected element
            if (selectedElement is IDynamicCanDelete)
                if (!(selectedElement as IDynamicCanDelete).CanDelete())
                {
                    // hide the command
                    cmd.Visible = false;
                    cmd.Enabled = false;
                    return;
                }

            // call the base implementation
            baseFunction(cmd);
        }
        
        /// <summary>
        /// Use this method from within the MyLanguageExplorer class
        /// in the ProcessOnStatusDeleteAllCommand() method.
        /// </summary>
        /// <example>
        /// partial class MyLanguageExplorer
        /// {
        ///    protected override void ProcessOnStatusDeleteAllCommand(MenuCommand cmd)
        ///    {
        ///        OnStatusDeleteCommandLogic.ForExplorerDeleteAll(cmd, this.ObjectModelBrowser.SelectedNode, base.ProcessOnStatusDeleteAllCommand);
        ///    }
        /// }
        /// </example>
        public static void ForExplorerDeleteAll(MenuCommand cmd, TreeNode selectedNode, Action<MenuCommand> baseFunction)
        {
            TreeNode n = selectedNode;
            if (n != null)
            {
                // check all children
                foreach (object node in n.Nodes)
                {
                    if (node is ModelElementTreeNode)
                    {
                        // the model element
                        ModelElement elem = (node as ModelElementTreeNode).ModelElement;
                        if (elem is IDynamicCanDelete)
                            if (!(elem as IDynamicCanDelete).CanDelete())
                            {
                                // hide the command
                                cmd.Visible = false;
                                cmd.Enabled = false;
                                return;
                            }
                    }
                }
            }

            // call the base implementation
            baseFunction(cmd);
        }

    }
}